package com.ztm.shortlink.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ztm.shortlink.admin.common.context.BaseContext;
import com.ztm.shortlink.admin.common.convention.result.Result;
import com.ztm.shortlink.admin.dao.entity.GroupDO;
import com.ztm.shortlink.admin.dao.mapper.GroupMapper;
import com.ztm.shortlink.admin.dto.req.GroupOrderReqDTO;
import com.ztm.shortlink.admin.dto.req.GroupUpdateReqDTO;
import com.ztm.shortlink.admin.dto.resp.GroupListRespDTO;
import com.ztm.shortlink.admin.remote.ShortLinkRemoteService;
import com.ztm.shortlink.admin.remote.dto.resp.ShortLinkCountQueryRespDTO;
import com.ztm.shortlink.admin.service.GroupService;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

@Service
public class GroupServiceImpl extends ServiceImpl<GroupMapper, GroupDO> implements GroupService {

    ShortLinkRemoteService shortLinkRemoteService = new ShortLinkRemoteService(){};


    /**
     * 新增短链接分组
     * @param name
     */
    @Override
    public void groupSave(String name) {
        //如果新增分组时只传分组名，则从token中获取用户名
        this.groupSave(BaseContext.getCurrentUsername(),name);
    }

    /**
     * 新增短链接分组
     * @param name
     */
    @Override
    public void groupSave(String username,String name) {
        //根据用户名和短链接分组名新增短链接分组

        //生成gid
        String gid = "";
        //循环生成gid，直到该用户名下没有该gid
        do{
            gid = RandomUtil.randomString(6);
        }while(hasGid(username,gid));

        GroupDO groupDO = GroupDO.builder()
                .gid(gid)
                .name(name)
                .username(username)
                .sortOrder(0)
                .build();
        baseMapper.insert(groupDO);
    }

    /**
     * 删除短链接分组
     * @param gid
     */
    @Override
    public void groupDelete(String gid) {
        //更新del_flag字段为1

        GroupDO groupDO = new GroupDO();
        groupDO.setDelFlag(1);
        LambdaQueryWrapper<GroupDO> queryWrapper = Wrappers.lambdaQuery(GroupDO.class)
                .eq(GroupDO::getGid, gid)
                .eq(GroupDO::getUsername, BaseContext.getCurrentUsername());
        baseMapper.update(groupDO,queryWrapper);
    }

    /**
     * 修改短链接分组
     * @param requestParam
     */
    @Override
    public void groupUpdate(GroupUpdateReqDTO requestParam) {
        //修改短链接分组名

        GroupDO groupDO = new GroupDO();
        groupDO.setName(requestParam.getName());
        LambdaQueryWrapper<GroupDO> queryWrapper = Wrappers.lambdaQuery(GroupDO.class)
                .eq(GroupDO::getGid, requestParam.getGid())
                .eq(GroupDO::getUsername, BaseContext.getCurrentUsername())
                .eq(GroupDO::getDelFlag, 0);
        baseMapper.update(groupDO,queryWrapper);
    }

    /**
     * 查询短链接分组
     * @return
     */
    @Override
    public List<GroupListRespDTO> groupList() {
        //根据username查询短链接分组列表
        LambdaQueryWrapper<GroupDO> queryWrapper = Wrappers.lambdaQuery(GroupDO.class)
                .eq(GroupDO::getUsername, BaseContext.getCurrentUsername())
                .eq(GroupDO::getDelFlag, 0)
                .orderByDesc(GroupDO::getSortOrder, GroupDO::getUpdateTime);
        //查询到的列表
        List<GroupDO> groupDOs = baseMapper.selectList(queryWrapper);

        //远程调用，查询每个分组下短链接数量

        //获取分组标识列表
        List<String> gidList = groupDOs.stream().map(GroupDO::getGid).toList();
        //发起远程调用
        Result<List<ShortLinkCountQueryRespDTO>> listResult =
                shortLinkRemoteService.listGroupShortLinkCount(gidList);

        //构建返回参数对象
        List<GroupListRespDTO> groupListRespDTOS = BeanUtil.copyToList(groupDOs, GroupListRespDTO.class);

        //把每个分组下的短链接数量设置到返回参数对象中去
        groupListRespDTOS.forEach(each->{
            Optional<ShortLinkCountQueryRespDTO> first = listResult.getData().stream()
                    .filter(item -> Objects.equals(item.getGid(), each.getGid()))
                    .findFirst();
            first.ifPresent(item->each.setShortLinkCount(first.get().getShortLinkCount()));

        });
        return groupListRespDTOS;
    }

    /**
     * 短链接分组排序
     * @param requestParam
     */
    @Override
    public void groupOrder(List<GroupOrderReqDTO> requestParam) {
        //把每个分组的排序分更新到数据库
        requestParam.forEach(GroupOrderReqDTO->{
            GroupDO groupDO = GroupDO.builder()
                    .sortOrder(GroupOrderReqDTO.getSortOrder())
                    .build();
            LambdaQueryWrapper<GroupDO> queryWrapper = Wrappers.lambdaQuery(GroupDO.class)
                    .eq(GroupDO::getGid, GroupOrderReqDTO.getGid())
                    .eq(GroupDO::getUsername, BaseContext.getCurrentUsername())
                    .eq(GroupDO::getDelFlag, 0);
            baseMapper.update(groupDO,queryWrapper);
        });
    }

    /**
     * 判断gid是否已经存在
     * @param gid
     * @return
     */
    private boolean hasGid(String username,String gid){
        //同一用户名下是否已经有该gid
        LambdaQueryWrapper<GroupDO> queryWrapper = Wrappers.lambdaQuery(GroupDO.class)
                .eq(GroupDO::getGid, gid)
                .eq(GroupDO::getUsername, username)
                .eq(GroupDO::getDelFlag, 0);
        GroupDO groupDO = baseMapper.selectOne(queryWrapper);
        return groupDO!=null;
    }
}
